from typing import Optional


class IdCard:
    def __init__(self, codes: str):
        check_result = IdCard._check_codes(codes)
        if check_result is None:
            raise ValueError(f"{codes} 不是合法的身份证号。")
        self._codes = check_result

    def get_codes(self):
        def to_char(value: int) -> str:
            return "X" if value == 10 else str(value)
        return "".join(map(to_char, self._codes[0:-1]))

    @staticmethod
    def _check_codes(codes: str) -> Optional[list[int]]:
        if len(codes) != 18:
            return None
        try:
            numbers = [int(c) for c in codes[0:-1]]
        except ValueError:
            return None
        factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        sum_value = 0
        for n, f in zip(numbers, factors):
            sum_value += n * f
        numbers.append(12 - sum_value % 11)
        if numbers[-1] == 10:
            if codes[-1].lower() != "x":
                return None
            return numbers
        else:
            if str(numbers[-1]) != codes[-1]:
                return None
            return numbers

    @staticmethod
    def _list_to_int(values: list[int]) -> int:
        result = 0
        factor = 10 ** (len(values) - 1)
        for value in values:
            result += value * factor
            factor //= 10
        return result

    def get_birthday(self) -> tuple[int, int, int]:
        year = IdCard._list_to_int(self._codes[6:10])
        month = IdCard._list_to_int(self._codes[10:12])
        date = IdCard._list_to_int(self._codes[12:14])
        return year, month, date


def _main():
    input_value = input("请输入身份证号：")
    try:
        id_card = IdCard(input_value)
    except ValueError:
        print(f"{input_value} 不是合法的身份证号（可能是因为长度不正确、含非法字符、校验位校验失败）。")
        return

    print("    身份证号          出生年月日")
    year, month, date = id_card.get_birthday()
    birthday_string = str(year) + "年" + str(month).zfill(2) + "月" + str(date).zfill(2) + "日"
    print(f"{id_card.get_codes()} {birthday_string}")


if __name__ == "__main__":
    _main()
